﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using VisionCloud.Core.Model.Ms;
using VisionCloud.Domain.DtoModel.Applet.RequestDto;
using VisionCloud.Domain.DtoModel.Applet.ResponseDto;
using VisionCloud.Domain.DtoModel.Ms;
using VisionCloud.Domain.Repository.Interface.Ms;

namespace VisionCloud.Domain.Repository.Implement.Ms
{
    public class MsHouseMapDetailsRepository : BaseRepository<MsHouseMapDetails>, IMsHouseMapDetailsRepository
    {
        private readonly IConfiguration cfg;
        private string wwwRoot;

        public MsHouseMapDetailsRepository(IConfiguration configuration)
        {
            this.cfg = configuration;
        }

        public async Task<List<PointLocationInfo>> GetHouseMapPointsByFloor(Guid projectId, string building, string floor)
        {
            return await (from md in Db.MsHouseMapDetails
                          join mp in Db.MsHouseMapPoints on md.HouseMapId equals mp.HouseMapId
                          where md.ProjectId == projectId && md.BuildingName == building && md.FloorName == floor && !md.IsDeleted
                          orderby mp.PointIndex
                          select new PointLocationInfo
                          {
                              HouseTypeName = mp.HouseTypeName,
                              OffsetX = mp.offsetX,
                              OffsetY = mp.offsetY,
                              Xpos = mp.x,
                              Ypos = mp.y,
                              PointIndex = mp.PointIndex,
                          }).ToListAsync();
        }

        public async Task<HouseMapPointsdto> GetHouseMapByFloor(QueryHouseMapDto condition)
        {
            HouseMapPointsdto result = new HouseMapPointsdto();

            var query = from d in Db.MsHouseMapDetails
                        join p in Db.MsProjects on d.ProjectId equals p.ProjectId
                        join h in Db.MsHouseMaps on d.HouseMapId equals h.HouseMapId
                        where d.ProjectId == condition.ProjectId && d.BuildingName == condition.Building && d.FloorName == condition.Floor && !d.IsDeleted
                        select new { ProjectName = p.Name, HouseMapName = h.Name, h.DataType, h.Image_Base, h.HouseMapId };

            var queryResult = await query.FirstOrDefaultAsync();
            if (queryResult != null)
            {
                result.ProjectName = queryResult.ProjectName;
                result.HouseMapName = queryResult.HouseMapName;
                result.HouseMapImage = GetHouseMapImageUrl(queryResult.DataType ?? 0, queryResult.Image_Base);
                result.Points = await GetHouseMapPoints(queryResult.HouseMapId);
            }
            return result;

            #region 本地方法

            string GetHouseMapImageUrl(int dataType, string image_Base) => dataType switch
            {
                0 => $"{cfg["FileServer"]}/{cfg["FileUploadFileMaster"]}/{cfg["FileUploadFileSon"]}/{image_Base}",
                1 => $"{cfg["FileServer"]}/algorithmreport{image_Base.Replace("algorithm-report", "")}",
                2 => $"{cfg["FileServer"]}/algorithmreport{image_Base.Replace("algorithm-report", "")}",
                _ => null
            };

            async Task<List<PointLocationInfo>> GetHouseMapPoints(Guid houseMapId)
            {
                return await Db.MsHouseMapPoints.Where(x => x.HouseMapId == houseMapId).Select(mp => new PointLocationInfo
                {
                    HouseTypeName = mp.HouseTypeName,
                    OffsetX = mp.offsetX,
                    OffsetY = mp.offsetY,
                    Xpos = mp.x,
                    Ypos = mp.y,
                    PointIndex = mp.PointIndex,
                }).ToListAsync();
            }

            #endregion 本地方法
        }

        public async ValueTask<List<HousemapBuildingFloorDto>> GetHouseMapBuildingFloorsAsync(Guid projectId)
        {
            var list = await Db.MsHouseMapDetails.Where(p => p.ProjectId == projectId).Select(p => new HousemapBuildingFloorDto
            {
                ProjectId = p.ProjectId,
                BuildingName = p.BuildingName,
                FloorName = p.FloorName,
                HouseMapId = p.HouseMapId
            }).ToListAsync();
            return list;
        }
    }

    public class MsHouseMapPointRepository : BaseRepository<MsHouseMapPoint>, IMsHouseMapPointRepository
    {
        /// <summary>
        /// 根据户型图Id获取站点信息
        /// </summary>
        /// <param name="houseMapId">户型图Id</param>
        /// <returns></returns>
        public async Task<List<MsHouseMapPoint>> Get(Guid houseMapId)
        {
            var points = await (
                          from h in Db.MsHouseMapPoints
                          where h.HouseMapId == houseMapId
                          select h
                         ).AsNoTracking().ToListAsync().ConfigureAwait(false);
            return points;
        }

        public async Task<List<MsHouseMapPoint>> GetMsHouseMapPointList(Guid houseMapId)
        {
            var points = (
                          from h in Db.MsHouseMapPoints
                          where h.HouseMapId == houseMapId
                          select h
                         ).ToListAsync().ConfigureAwait(true);
            return await points;
        }

        public async Task<List<MsHouseMapPoint>> GetDataByHouseMapIds(Guid[] houseMapIds)
        {
            var points = (
                        from h in Db.MsHouseMapPoints
                        where houseMapIds.Contains(h.HouseMapId)
                        select h
                       ).AsNoTracking().ToListAsync().ConfigureAwait(false);
            return await points;
        }

        public async Task<List<HouseType>> GetHouseTypes(Guid taskId)
        {
            return await (from t in Db.MsTasks
                          join h in Db.MsHouseMapPoints on t.HouseMapId equals h.HouseMapId
                          join c in Db.MsPointCompleteds on new { t.TaskId, h.PointIndex } equals new { c.TaskId, c.PointIndex }
                          where t.TaskId == taskId && h.HouseTypeKey != null && t.MeasureType == "0"
                          select new HouseType { Key = h.HouseTypeKey.ToString(), Name = h.HouseTypeName }).Distinct().OrderBy(x => x.Name).AsNoTracking().ToListAsync().ConfigureAwait(false);
        }
    }
}